// mysignal.cc
#include <iostream>
#include <cstring>
#include <ctime>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

int main()
{
    printf("pid is: %d\n", getpid());
    while(1);
    return 0;
}

// void handler(int signo)
// {
//     sleep(3);
//     pid_t rid;
//     while ((rid = waitpid(-1, nullptr, WNOHANG)) > 0)
//     {
//         cout << "I am process: " << getpid()
//              << " catch a signo: " << signo
//              << " child process quit: " << rid << endl;
//     }
// }

// int main()
// {
//     srand(time(nullptr));
//     //signal(17, handler);
//     signal(17, SIG_IGN);

//     // 当有10个子进程时，如果同时退出，要防止同一信号多次发送的丢失问题，因此进程等待要循环等待
//     // 如果只退出一半，注意不能让父进程卡在进程等待那里，所以要设置为非阻塞轮询
//     for (int i = 0; i < 10; ++i)
//     {
//         pid_t id = fork();
//         if (id == 0)
//         {
//             while (true)
//             {
//                 cout << "I am child process, pid: " << getpid()
//                      << " ppid: " << getppid() << endl;
//                 sleep(rand() % 15 + 3);
//                 break;
//             }
//             cout << "child quit!!!" << endl;
//             exit(0);
//         }
//         rand();  // 作用：让每个子进程的随机数起始值不一样
//     }
//     // father
//     while (true)
//     {
//         cout << "I am father process: " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }

// volatile int flag = 0;  // volatile关键字：防止编译器过度优化，保持内存的可见性

// void handler(int signo)
// {
//     cout << "catch a signo: " << signo << endl;
//     flag = 1;
// }

// int main()
// {
//     signal(2, handler);

//     while (!flag);
//     // flag==0时，进程会卡在while循环这里；当收到2号信号时，会把flag改成1，就可以退出循环，结束进程

//     cout << "process quit normal" << endl;
//     return 0;
// }

// // 1. 执行信号捕捉方法之前，先把pending位图对应信号位清0，再处理信号
// // 2. 信号被处理的时候，对应的信号也会被添加到block表中，防止信号被嵌套调用

// // 获取并打印pending位图
// void PrintPending()
// {
//     sigset_t set;
//     sigpending(&set);
//     for (int signo = 31; signo > 0; --signo)
//     {
//         if (sigismember(&set, signo))
//             cout << "1";
//         else
//             cout << "0";
//     }
//     cout << endl;
// }

// void handler(int signo)
// {
//     //PrintPending();  // 如果signo位为0，表示在信号处理前，先把pending位图由1置0了
//     cout << "catch a signo: " << signo << endl;
//     while(1)
//     {
//         PrintPending();
//         sleep(1);
//     }
// }

// int main()
// {
//     struct sigaction act, oact;
//     memset(&act, 0, sizeof(act));  // 先把结构体全部置0置空
//     memset(&oact, 0, sizeof(oact));

//     // 在处理2号信号时同时屏蔽以下信号
//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask, 1);
//     sigaddset(&act.sa_mask, 3);
//     sigaddset(&act.sa_mask, 4);

//     act.sa_handler = handler;  // 也可以传SIG_IGN, SIG_DFL
//     sigaction(2, &act, &oact);  // 捕捉2号信号

//     while (1)
//     {
//         cout << "I am a process: " << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }